/*
 * MIT License
 *
 * Copyright (c) 2023 北京凯特伟业科技有限公司
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.je.workflow.service.usertask.vo;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.google.common.base.Strings;
import com.je.bpm.engine.impl.cmd.SubmitTypeEnum;
import com.je.bpm.engine.impl.identity.Authentication;
import com.je.common.base.DynaBean;
import com.je.common.base.spring.SpringContextHolder;
import com.je.workflow.service.user.WorkFlowUserService;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

public class UserTaskVo {
    /**
     * 主键
     */
    String id;
    /**
     * 标题
     */
    String title;
    /**
     * 内容
     */
    String context;
    /**
     * 收藏
     */
    String collect;
    /**
     * 延时
     */
    String delay;
    /**
     * 提交时间
     */
    String submitTime;
    /**
     * 表
     */
    String tableCode;
    /**
     * 功能
     */
    String funcCode;
    /**
     * 主键
     */
    String pkValue;
    /**
     * 提交人员id
     */
    String submitUserId;
    /**
     * 提交人员name
     */
    String submitUserName;
    /**
     * 提交人员name
     */
    String submitUserPhoto;
    /**
     * piid
     */
    String piid;
    /**
     * 紧急状态
     */
    String exigency;
    /**
     * 阅读状态
     */
    String isReadCode;

    String isReadName;

    private String funcName;

    public String getIsReadCode() {
        return isReadCode;
    }

    public void setIsReadCode(String isReadCode) {
        this.isReadCode = isReadCode;
    }

    public String getIsReadName() {
        return isReadName;
    }

    public void setIsReadName(String isReadName) {
        this.isReadName = isReadName;
    }

    public static UserTaskVo buildEndTask(DynaBean dynaBean) {
        return buildEndTask(dynaBean, new HashMap<>());
    }

    public static UserTaskVo buildEndTask(DynaBean dynaBean, Map<String, String> exigencys) {
        UserTaskVo vo = new UserTaskVo();
        vo.setId(dynaBean.getStr("JE_WORKFLOW_HI_TASK_ID"));
        vo.setSubmitTime(dynaBean.getStr("SY_CREATETIME"));
        vo.setTableCode(dynaBean.getStr("TABLE_CODE"));
        vo.setFuncCode(dynaBean.getStr("FUNC_CODE"));
        vo.setPkValue(dynaBean.getStr("BUSINESS_KEY"));
        vo.setFuncName(dynaBean.getStr("FUNC_NAME"));
        String collectTime = dynaBean.getStr("COLLECT_SY_CREATETIME");
        vo.setPiid(dynaBean.getStr("EXECUTION_PIID"));
        vo.setExigency(exigencys.get(dynaBean.getStr("EXECUTION_PIID")));
        if (Strings.isNullOrEmpty(collectTime)) {
            vo.setCollect("0");
        } else {
            vo.setCollect("1");
        }
        buildTitle(dynaBean, vo);
        buildConext(dynaBean, vo, true);
        return vo;
    }

    public static UserTaskVo buildRunTask(DynaBean dynaBean) {
        return buildRunTask(dynaBean, new HashMap<>());
    }

    public static UserTaskVo buildRunTask(DynaBean dynaBean, Map<String, String> exigencys) {
        UserTaskVo vo = new UserTaskVo();
        vo.setId(dynaBean.getStr("JE_WORKFLOW_RN_TASK_ID"));
        vo.setSubmitTime(dynaBean.getStr("SY_CREATETIME"));
        vo.setDelay(dynaBean.getStr("TASK_DELAY"));
        vo.setTableCode(dynaBean.getStr("TABLE_CODE"));
        vo.setFuncCode(dynaBean.getStr("FUNC_CODE"));
        vo.setPkValue(dynaBean.getStr("BUSINESS_KEY"));
        vo.setFuncName(dynaBean.getStr("FUNC_NAME"));
        String collectTime = dynaBean.getStr("COLLECT_SY_CREATETIME");
        vo.setPiid(dynaBean.getStr("EXECUTION_PIID"));
        vo.setExigency(exigencys.get(dynaBean.getStr("EXECUTION_PIID")));
        if (Strings.isNullOrEmpty(collectTime)) {
            vo.setCollect("0");
        } else {
            vo.setCollect("1");
        }
        buildConext(dynaBean, vo);
        buildTitle(dynaBean, vo);
        return vo;
    }

    private static void buildTitle(DynaBean dynaBean, UserTaskVo vo) {
        String title = dynaBean.getStr("EXECUTION_TITLE");
        try {
            String day = JudgmentDay(dynaBean.getStr("EXECUTION_START_TIME"));
            if (day == null) {
                day = dynaBean.getStr("EXECUTION_START_TIME").substring(0, 10);
            }
            try {
                title = String.format(title, "（" + day + "）");
            } catch (Exception e) {
                e.printStackTrace();
            }
            vo.setTitle(title);
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }

    private static void buildConext(DynaBean dynaBean, UserTaskVo vo) {
        buildConext(dynaBean, vo, false);
    }

    private static void buildConext(DynaBean dynaBean, UserTaskVo vo, Boolean isEnd) {
        String assigneeJson = dynaBean.getStr("EXECUTION_ASSIGNEE_JSON");
        //如果我是提交人，显示全部人员信息
        Boolean isMe = false;
        if (!isEnd && dynaBean.getStr("EXECUTION_SUBMIET_USER_ID").equals(Authentication.getAuthenticatedUser().getDeptId())) {
            isMe = true;
        }
        String assigneeUserIds = "";
        String assigneeNames = "";
        if (!isEnd) {
            JSONArray jsonArray = JSONArray.parseArray(assigneeJson);
            Map<String, String> map = buildAssigneeJson(jsonArray, isMe, dynaBean.getStr("EXECUTION_NODE_ID"), dynaBean.getStr("TASK_HANDLE"), dynaBean.getStr("EXECUTION_SUBMIT_TYPE"));
            assigneeUserIds = map.get("userId");
            assigneeNames = map.get("userName");
        }
        String submitType = "";
        String comment = "";
        String submitUserName = "";
        String submitUserId = "";
        String assigneeName = assigneeNames;
        String assigneeId = assigneeUserIds;
        if (assigneeId.contains(Authentication.getAuthenticatedUser().getDeptId())) {
            assigneeName = "我";
        }
        if (Strings.isNullOrEmpty(dynaBean.getStr("TASK_SUBMIT_TYPE_CODE"))) {
            submitType = dynaBean.getStr("EXECUTION_SUBMIT_TYPE");
            comment = dynaBean.getStr("EXECUTION_LAST_COMMENT");
            if (Strings.isNullOrEmpty(comment)) {
                comment = dynaBean.getStr("EXECUTION_COMMENT");
            }
            submitUserName = dynaBean.getStr("EXECUTION_SUBMIT_USER_NAME");
            vo.setSubmitUserName(submitUserName);
            submitUserId = dynaBean.getStr("EXECUTION_SUBMIET_USER_ID");
        } else {
            submitType = dynaBean.getStr("TASK_SUBMIT_TYPE_CODE");
            comment = dynaBean.getStr("TASK_SUBMIT_COMMENT");
            submitUserName = dynaBean.getStr("TASK_SUBMIT_USER_NAME");
            submitUserId = dynaBean.getStr("TASK_SUBMIT_USER_ID");
        }
        if (!isEnd && submitUserId.equals(Authentication.getAuthenticatedUser().getDeptId())) {
            submitUserName = "我";
        }

        if (isEnd) {
            if (dynaBean.getStr("SY_CREATEUSERID").equals(Authentication.getAuthenticatedUser().getDeptId())) {
                submitUserName = "我";
            } else {
                submitUserName = dynaBean.getStr("SY_CREATEUSERNAME");
                vo.setSubmitUserName(submitUserName);
            }
            submitType = "END";
        }

        String submitTypeName = SubmitTypeEnum.getNameByType(submitType);

        String context = "";
        //判断模板内容是否为空，如果不为空，设置拼接自定义内容显示
        if (Strings.isNullOrEmpty(dynaBean.getStr("EXECUTION_CONTENT"))) {
            String time = vo.getSubmitTime();
            if (isEnd) {
                time = dynaBean.getStr("SY_CREATETIME");
                submitType = dynaBean.getStr("EXECUTION_COMMIT_TYPE");
            }
            if (submitType.equals(SubmitTypeEnum.GOBACK.toString()) || submitType.equals(SubmitTypeEnum.DISMISS.toString())) {
                if (Strings.isNullOrEmpty(assigneeName)) {
                    assigneeName = "我";
                }
                context = String.format("%s，由%s【<span class=\"flow-remark\">%s给%s</span>】，意见：%s",
                        time, submitUserName, submitTypeName, assigneeName, comment);
            } else if (submitType.equals(SubmitTypeEnum.START.toString())) {
                context = String.format("%s，由我【%s】",
                        time, submitTypeName);
            } else if (submitType.equals(SubmitTypeEnum.INVALID.toString())) {
                assigneeName = dynaBean.getStr("SY_CREATEUSERNAME");
                context = String.format("%s，由%s【作废】，意见：%s",
                        time, assigneeName, comment);
            } else if (isEnd) {
                context = String.format("%s，由%s【审批结束】",
                        time, submitUserName);
            } else if (submitType.equals(SubmitTypeEnum.RECEIVE.toString()) || submitType.equals(SubmitTypeEnum.RETRIEVE.toString())
                    || submitType.equals(SubmitTypeEnum.CANCELDELEGATE.toString())) {
                context = String.format("%s，由%s【%s任务】",
                        time, submitUserName, submitTypeName);
            } else if (submitType.equals(SubmitTypeEnum.PASS.toString()) || submitType.equals(SubmitTypeEnum.VETO.toString())) {
                if (Strings.isNullOrEmpty(assigneeName)) {
                    assigneeName = "我";
                }
                context = String.format("%s，由多人节点审核【%s给%s】",
                        time, submitTypeName, assigneeName);
            } else {
                context = String.format("%s，由%s【%s给%s】，意见：%s",
                        time, submitUserName, submitTypeName, assigneeName, comment);
            }

        } else {
            context = dynaBean.getStr("EXECUTION_CONTENT");
        }

        WorkFlowUserService workFlowUserService = SpringContextHolder.getBean(WorkFlowUserService.class);
        if (!Strings.isNullOrEmpty(workFlowUserService.getUserPhotoById(dynaBean.getStr("EXECUTION_STARTER")))) {
            String photoJson = workFlowUserService.getUserPhotoById(dynaBean.getStr("EXECUTION_STARTER"));
            if (!Strings.isNullOrEmpty(photoJson)) {
                try {
                    JSONObject jsonObject = JSONArray.parseArray(photoJson).getJSONObject(0);
                    vo.setSubmitUserPhoto(jsonObject.getString("fileKey"));
                } catch (Exception e) {
                    e.printStackTrace();
                    vo.setSubmitUserPhoto("");
                }
            }
        } else {
            vo.setSubmitUserPhoto("");
        }
        vo.setSubmitUserName(dynaBean.getStr("EXECUTION_STARTER_NAME"));
        vo.setContext(context);
    }


    private static Map<String, String> buildAssigneeJson(JSONArray jsonArray, Boolean isMe, String currentNodeId, String isHandle
            , String submitType) {
        Map<String, String> users = new HashMap<>();
        if (jsonArray == null) {
            return users;
        }
        Set<String> userIds = new HashSet<>();
        Set<String> userNames = new HashSet<>();
        for (Object jsonObject : jsonArray) {
            JSONObject object = (JSONObject) jsonObject;
            if (currentNodeId.equals(object.getString("nodeId"))) {
                if (!Strings.isNullOrEmpty(object.getString("assignee"))) {
                    userIds.add(object.getString("assignee"));
                }
                if (!Strings.isNullOrEmpty(object.getString("assigneeName"))) {
                    userNames.add(object.getString("assigneeName"));
                }
            }
        }
        if (userIds.size() > 0 && userNames.size() == 0) {
            WorkFlowUserService workFlowUserService = SpringContextHolder.getBean(WorkFlowUserService.class);
            for (String userId : userIds) {
                userNames.add(workFlowUserService.getUserNameById(userId));
            }
        }
        String userIdsStr = String.join("、", userIds);
        String userNameStr = String.join("、", userNames);
        users.put("userId", userIdsStr);
        users.put("userName", userNameStr);
        return users;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getContext() {
        return context;
    }

    public void setContext(String context) {
        this.context = context;
    }

    public String getCollect() {
        return collect;
    }

    public void setCollect(String collect) {
        this.collect = collect;
    }

    public String getDelay() {
        return delay;
    }

    public void setDelay(String delay) {
        this.delay = delay;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getSubmitTime() {
        return submitTime;
    }

    public void setSubmitTime(String submitTime) {
        this.submitTime = submitTime;
    }


    /**
     * 判断日期(效率比较高)
     */
    public static String JudgmentDay(String day) throws ParseException {
        Calendar pre = Calendar.getInstance();
        Date predate = new Date(System.currentTimeMillis());
        pre.setTime(predate);

        Calendar cal = Calendar.getInstance();
        Date date = getDateFormat().parse(day);
        cal.setTime(date);

        if (cal.get(Calendar.YEAR) == (pre.get(Calendar.YEAR))) {
            int diffDay = cal.get(Calendar.DAY_OF_YEAR)
                    - pre.get(Calendar.DAY_OF_YEAR);

            switch (diffDay) {
                case YESTERDY: {
                    return "今天";
                }
                case TODAY: {
                    return "昨天";
                }
            }
        }

        if (isDateInCurrentWeek(date)) {
            SimpleDateFormat dateFm = new SimpleDateFormat("EEEE", Locale.SIMPLIFIED_CHINESE);
            return dateFm.format(date);
        }

        return null;
    }

    public static boolean isDateInCurrentWeek(Date date) {
        Calendar calendar = Calendar.getInstance(Locale.SIMPLIFIED_CHINESE);
        int currentWeek = calendar.get(Calendar.WEEK_OF_YEAR);
        calendar.setTime(date);
        int paramWeek = calendar.get(Calendar.WEEK_OF_YEAR);
        if (paramWeek == currentWeek) {
            return true;
        }
        return false;
    }


    private static final int YESTERDY = 0;
    private static final int TODAY = -1;
    private static ThreadLocal DateLocal = new ThreadLocal();

    public static SimpleDateFormat getDateFormat() {
        if (null == DateLocal.get()) {
            DateLocal.set(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA));
        }
        return (SimpleDateFormat) DateLocal.get();
    }

    public String getTableCode() {
        return tableCode;
    }

    public void setTableCode(String tableCode) {
        this.tableCode = tableCode;
    }

    public String getFuncCode() {
        return funcCode;
    }

    public void setFuncCode(String funcCode) {
        this.funcCode = funcCode;
    }

    public String getPkValue() {
        return pkValue;
    }

    public void setPkValue(String pkValue) {
        this.pkValue = pkValue;
    }

    public static int getYESTERDY() {
        return YESTERDY;
    }

    public static int getTODAY() {
        return TODAY;
    }

    public static ThreadLocal getDateLocal() {
        return DateLocal;
    }

    public static void setDateLocal(ThreadLocal dateLocal) {
        DateLocal = dateLocal;
    }

    public String getSubmitUserId() {
        return submitUserId;
    }

    public void setSubmitUserId(String submitUserId) {
        this.submitUserId = submitUserId;
    }

    public String getSubmitUserName() {
        return submitUserName;
    }

    public void setSubmitUserName(String submitUserName) {
        this.submitUserName = submitUserName;
    }

    public String getSubmitUserPhoto() {
        return submitUserPhoto;
    }

    public void setSubmitUserPhoto(String submitUserPhoto) {
        this.submitUserPhoto = submitUserPhoto;
    }

    public String getPiid() {
        return piid;
    }

    public void setPiid(String piid) {
        this.piid = piid;
    }


    public String getFuncName() {
        return funcName;
    }

    public void setFuncName(String funcName) {
        this.funcName = funcName;
    }

    public String getExigency() {
        return exigency;
    }

    public void setExigency(String exigency) {
        this.exigency = exigency;
    }
}
